package org.example.short_link.admin.common.biz.user;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.example.short_link.admin.common.convention.Exception.ClientException;
import org.example.short_link.admin.common.convention.result.Results;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Objects;
import static org.example.short_link.admin.common.enums.UserErrorCdeEnum.USER_TOKEN_FAIL;

/**
 * 用户信息传输过滤器
 *
 *
 */
@RequiredArgsConstructor
public class UserTransmitFilter implements Filter {

    private static final List<String> IGNORE_URI = Lists.newArrayList(
            "/api/short-link/admin/v1/user/login",
            "/api/short-link/admin/v1/actual/user/has-username"
    );

    private final StringRedisTemplate stringRedisTemplate;

    @SneakyThrows
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String requestURI = httpServletRequest.getRequestURI();
        //如果不包含以下链接，就需要验证tokne 和 username
        if(!IGNORE_URI.contains(requestURI)){
            String method = httpServletRequest.getMethod();
            //如果不是以下链接并且请求方式不是POST的话 就需要验证
            if(!(Objects.equals(requestURI,"/api/short-link/admin/v1/user") && Objects.equals(method,"POST"))){
                String username = httpServletRequest.getHeader("username");
                String token = httpServletRequest.getHeader("token");
                //如果此时 username和token不存在就抛出ClientException错误
                if(!StrUtil.isAllNotBlank(username,token)){
                    retuenJSON((HttpServletResponse) servletResponse,JSON.toJSONString(Results.failure(new ClientException(USER_TOKEN_FAIL))));
                    return;
                }
                //通过username 和 token 获取到缓存对象
                Object userInfoJsonStr;

                try {
                    //在redis中查询是否存在
                    userInfoJsonStr = stringRedisTemplate.opsForHash().get("login_" + username, token);
                    if(userInfoJsonStr == null){
                        throw new ClientException(USER_TOKEN_FAIL);
                    }
                }catch (Exception ex){
                    retuenJSON((HttpServletResponse) servletResponse,JSON.toJSONString(Results.failure(new ClientException(USER_TOKEN_FAIL))));
                    return;

                }
                    //JSON.parseObject，是将Json字符串转化为相应的对象；
                    UserInfoDTO userInfoDTO = JSON.parseObject(userInfoJsonStr.toString(),UserInfoDTO.class);
                    UserContext.setUser(userInfoDTO);
            }
        }
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            UserContext.removeUser();
        }
    }

    private void retuenJSON(HttpServletResponse response , String json) throws Exception{
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        try {
            writer = response.getWriter();
            writer.print(json);
        }catch (IOException e){

        }finally {
            if(writer != null){
                writer.close();
            }
        }



    }










}
